package com.xiaobai.controller;

import com.xiaobai.bo.ReportInfo;
import com.xiaobai.common.AddressEnum;
import com.xiaobai.common.ServiceResponse;
import com.xiaobai.config.MyStudentIdManager;
import com.xiaobai.config.SchedulingTask;
import com.xiaobai.dao.HealthInfoDao;
import com.xiaobai.dao.HealthLogDao;
import com.xiaobai.pojo.HealthInfo;
import com.xiaobai.pojo.HealthLog;
import com.xiaobai.service.addition.IHealthReportService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @description: 扩展功能接口
 * @author: 小白白
 * @create: 2021-09-15
 **/

@RestController
@RequestMapping("/health-report")
public class HealthReportController {

    private static final String LIMIT_KEY = "action_limit:";

    @Autowired
    private IHealthReportService healthReportService_v2;

    @Autowired
    private HealthLogDao healthLogDao;

    @Autowired
    private HealthInfoDao healthInfoDao;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SchedulingTask schedulingTask;

    /**
     * 开启打开&&设置打卡属性
     * [地点 打卡时间]
     * 0:00 ~ 0:10 为系统调整时间,不可设置
     */
    @PostMapping("/login-open")
    public ServiceResponse open(@RequestBody @Validated ReportInfo reportInfo) {

        if (MyStudentIdManager.get().equals("111111")) {
            return ServiceResponse.createBySuccess();
        }

//        if (true) {
//            return ServiceResponse.fail("放假了,应该用不到了");
//        }
        if (!canDoAction()) {
            return ServiceResponse.fail("24小时内只能操作有限次");
        }
        String format = reportInfo.getTime();
        if (!format.contains(":")){
            return ServiceResponse.fail("error");
        }
        int hour;
        int min;
        try {
            String[] split = format.split(":");
            hour = Integer.parseInt(split[0]);
            min = Integer.parseInt(split[1]);
            if (hour == 0 && min >=0 && min <=5 ) {
                return ServiceResponse.fail("请重新设置打卡时间 范围[8:03~19:57]");
            }
            if (hour >= 20 || hour < 8) {
                return ServiceResponse.fail("请重新设置打卡时间 范围[8:03~19:57]");
            }
            if (hour == 8 && min < 3) {
                return ServiceResponse.fail("请重新设置打卡时间 范围[8:03~19:57]");
            }
            if (hour == 19 && min > 57) {
                return ServiceResponse.fail("请重新设置打卡时间 范围[8:03~19:57]");
            }
        }catch (Exception e){
            return ServiceResponse.fail("error!!!");
        }
        // 只能是教务网的账号
        String studentId = MyStudentIdManager.get();
        // 检验账号密码 (非代理形式)
        String loginResult = healthReportService_v2.validLogin(studentId, reportInfo.getPassword());
        if (!StringUtils.equals(loginResult, "密码正确")) {
            return ServiceResponse.fail(loginResult + "[请重试]");
        }

        HealthInfo healthInfo = new HealthInfo();
        healthInfo.setStudentId(studentId);
        healthInfo.setPassword(reportInfo.getPassword());
        healthInfo.setTimingStr(format);
        healthInfo.setAddressId(reportInfo.getAddressId());
        healthInfo.setAddress(reportInfo.getAddress());
        healthInfo.setOpen(true);
        healthInfo.setCreateTime(new Date());

        // 更新或者保存
        healthInfoDao.saveOrUpdateByStudentId(healthInfo);

        // 登录成功时不默认打卡一次
//        Integer id = healthInfoDao.selectIdByStudentId(studentId);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,hour);
//        calendar.set(Calendar.MINUTE,min);
//        DelayIntTask delayIntTask = new DelayIntTask(id, calendar.getTime());
//        if (this.canDoAction()) {
//            // 加入时会自动remove
//            healthReportService_v2.addDelayTask(delayIntTask);
//        }

        return ServiceResponse.createBySuccess();
    }

    /**
     * 开启自动打卡
     */
    @GetMapping("/open")
    public ServiceResponse open() {

//        if (true) {
//            return ServiceResponse.fail("放假了,应该用不到了");
//        }
        String studentId = MyStudentIdManager.get();
        HealthInfo healthInfo = healthInfoDao.selectByStudentId(studentId);
        if (healthInfo == null) {
            return ServiceResponse.fail("配置不存在");
        }
        if (healthInfo.getOpen()) {
            return ServiceResponse.fail("已经是开启状态了");
        }
        // 开启时不默认打卡一次
//        if(canDoAction()) {
//            String format = healthInfo.getTimingStr();
//            String[] split = format.split(":");
//            int hour = Integer.parseInt(split[0]);
//            int min = Integer.parseInt(split[1]);
//            Calendar calendar = Calendar.getInstance();
//            calendar.set(Calendar.HOUR_OF_DAY,hour);
//            calendar.set(Calendar.MINUTE,min);
//            DelayIntTask delayIntTask = new DelayIntTask(healthInfo.getId(),calendar.getTime());
//            // 放入队列
//            healthReportService_v2.addDelayTask(delayIntTask);
//        }
        // 开启open
        healthInfoDao.openAction(healthInfo.getId());
        return ServiceResponse.createBySuccess();
    }

    /**
     * 关闭打卡
     */
    @GetMapping("/close")
    public ServiceResponse close() {

        String studentId = MyStudentIdManager.get();
        Integer id = healthInfoDao.selectIdByStudentId(studentId);
        if (id == null) {
            return ServiceResponse.fail("配置不存在");
        }
        // 移除队列
        healthReportService_v2.removeDelayTask(id);
        // 关闭open
        healthInfoDao.closeAction(id);
        return ServiceResponse.createBySuccess();
    }

    /**
     * 打卡配置信息item
     */
    @GetMapping("/item")
    public ServiceResponse item() {
        String studentId = MyStudentIdManager.get();

        HealthInfo healthInfo = healthInfoDao.selectByStudentId(studentId);
        return ServiceResponse.createBySuccess(healthInfo);
    }

    /**
     * 历史打卡记录
     */
    @GetMapping("/log")
    public ServiceResponse log(@RequestParam("pageNum")Integer pageNum,
                               @RequestParam("pageSize")Integer pageSize) {
        String studentId = MyStudentIdManager.get();
        int limitStart = (pageNum-1) * pageSize;
        int limitEnd = pageNum * pageSize;
        List<HealthLog> list = healthLogDao.limitPage(studentId, limitStart, limitEnd);
        return ServiceResponse.createBySuccess(list);
    }

    /**
     * 主动打卡一次(每天有次数的)
     */
    @GetMapping("/action")
    public ServiceResponse action() {

        if (MyStudentIdManager.get().equals("111111")) {
            HealthLog healthLog = new HealthLog();
            healthLog.setCreateTime(new Date());
            healthLog.setResult("测试打卡成功");
            healthLog.setStudentId("111111");
            healthLogDao.insert(healthLog);
            return ServiceResponse.createBySuccess("测试打卡成功");
        }

        if (!this.canDoAction()){
            return ServiceResponse.fail("24小时内只能操作有限次");
        }
        String studentId = MyStudentIdManager.get();
        HealthInfo healthInfo = healthInfoDao.selectByStudentId(studentId);
        if (healthInfo == null){
            return ServiceResponse.fail("未配置账号信息");
        }
        String address = AddressEnum.getAddress(healthInfo.getAddressId(), healthInfo.getAddress());
        String result = healthReportService_v2.doAction(healthInfo.getStudentId(), healthInfo.getPassword(), address, 0, false);
        if (!StringUtils.equals(result, "打卡成功")) {
            return ServiceResponse.fail(result);
        }
        return ServiceResponse.createBySuccess(result);
    }

    private boolean canDoAction() {
        String studentId = MyStudentIdManager.get();
        Long increment = stringRedisTemplate.opsForValue().increment(LIMIT_KEY + studentId);
        if (increment == 1) {
            // 设置过期时间,一天只有打3次卡
            stringRedisTemplate.expire(LIMIT_KEY + studentId,24, TimeUnit.HOURS);
        }
        return increment <= 3;
    }

}
